#!/bin/bash

# AI Agent Platform 开发环境设置脚本 (macOS/Linux)
# 作者: Claude
# 日期: 2025-01-19

set -e  # 遇到错误立即退出

# 颜色输出函数
print_info() {
    echo -e "\033[36mℹ️  $1\033[0m"
}

print_success() {
    echo -e "\033[32m✅ $1\033[0m"
}

print_warning() {
    echo -e "\033[33m⚠️  $1\033[0m"
}

print_error() {
    echo -e "\033[31m❌ $1\033[0m"
}

print_step() {
    echo -e "\033[34m🔧 $1\033[0m"
}

# 检查命令是否存在
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# 检查 .NET SDK
check_dotnet() {
    print_step "检查 .NET SDK..."

    if command_exists dotnet; then
        local dotnet_version=$(dotnet --version)
        print_success "✓ .NET SDK 已安装: $dotnet_version"

        local major_version=$(echo "$dotnet_version" | cut -d. -f1)
        if [ "$major_version" -lt 8 ]; then
            print_error "需要 .NET 8.0 或更高版本，当前版本: $dotnet_version"
            return 1
        fi
        return 0
    else
        print_error "✗ .NET SDK 未安装"
        print_warning "请从 https://dotnet.microsoft.com/download 下载 .NET 8.0 SDK"
        return 1
    fi
}

# 检查 Node.js (可选)
check_node() {
    print_step "检查 Node.js..."

    if command_exists node; then
        local node_version=$(node --version)
        print_success "✓ Node.js 已安装: $node_version"
        return 0
    else
        print_warning "⚠️  Node.js 未安装 (可选，用于前端开发)"
        return 1
    fi
}

# 检查 Git
check_git() {
    print_step "检查 Git..."

    if command_exists git; then
        local git_version=$(git --version)
        print_success "✓ Git 已安装: $git_version"
        return 0
    else
        print_error "✗ Git 未安装"
        print_warning "请根据您的操作系统安装 Git"
        return 1
    fi
}

# 检查 Docker (可选)
check_docker() {
    if [ "$SKIP_DOCKER" = true ]; then
        print_warning "⚠️  跳过 Docker 检查"
        return 0
    fi

    print_step "检查 Docker..."

    if command_exists docker; then
        local docker_version=$(docker --version)
        print_success "✓ Docker 已安装: $docker_version"
        return 0
    else
        print_warning "⚠️  Docker 未安装 (可选，用于容器化)"
        return 1
    fi
}

# 设置数据库
setup_database() {
    if [ "$SKIP_DATABASE" = true ]; then
        print_warning "⚠️  跳过数据库设置"
        return 0
    fi

    print_step "设置数据库..."

    case "$DATABASE_TYPE" in
        "SqlServer")
            setup_sql_server
            ;;
        "PostgreSQL")
            setup_postgresql
            ;;
        "MySQL")
            setup_mysql
            ;;
        *)
            print_error "✗ 不支持的数据库类型: $DATABASE_TYPE"
            return 1
            ;;
    esac
}

# 设置 SQL Server (使用 Docker)
setup_sql_server() {
    print_step "检查 SQL Server..."

    if command_exists sqlcmd; then
        print_success "✓ SQL Server 客户端已安装"
        return 0
    fi

    if [ "$SKIP_DOCKER" = false ] && command_exists docker; then
        print_step "尝试启动 SQL Server Docker 容器..."

        # 检查容器是否已存在
        if docker ps -a --format 'table {{.Names}}' | grep -q "sql_server_demo"; then
            if docker ps --format 'table {{.Names}}' | grep -q "sql_server_demo"; then
                print_success "✓ SQL Server 容器已在运行"
                return 0
            else
                print_step "启动现有 SQL Server 容器..."
                docker start sql_server_demo
                print_success "✓ SQL Server 容器已启动"
                return 0
            fi
        fi

        # 启动新容器
        docker run -d --name sql_server_demo \
            -e "ACCEPT_EULA=Y" \
            -e "MSSQL_SA_PASSWORD=yourStrong(!)Password" \
            -p 1433:1433 \
            mcr.microsoft.com/mssql/server:2022-latest

        print_success "✓ SQL Server Docker 容器已启动"
        print_warning "请等待 1-2 分钟让容器完全启动"
        return 0
    else
        print_warning "⚠️  请手动安装 SQL Server 或使用 Docker"
        return 1
    fi
}

# 设置 PostgreSQL
setup_postgresql() {
    print_step "检查 PostgreSQL..."

    if command_exists psql; then
        print_success "✓ PostgreSQL 客户端已安装"
        return 0
    fi

    if [ "$SKIP_DOCKER" = false ] && command_exists docker; then
        print_step "尝试启动 PostgreSQL Docker 容器..."

        # 检查容器是否已存在
        if docker ps -a --format 'table {{.Names}}' | grep -q "postgres"; then
            if docker ps --format 'table {{.Names}}' | grep -q "postgres"; then
                print_success "✓ PostgreSQL 容器已在运行"
                return 0
            else
                print_step "启动现有 PostgreSQL 容器..."
                docker start postgres
                print_success "✓ PostgreSQL 容器已启动"
                return 0
            fi
        fi

        # 启动新容器
        docker run -d --name postgres \
            -e POSTGRES_PASSWORD=yourpassword \
            -p 5432:5432 \
            postgres:13

        print_success "✓ PostgreSQL Docker 容器已启动"
        return 0
    else
        print_warning "⚠️  请手动安装 PostgreSQL 或使用 Docker"
        return 1
    fi
}

# 设置 MySQL
setup_mysql() {
    print_step "检查 MySQL..."

    if command_exists mysql; then
        print_success "✓ MySQL 客户端已安装"
        return 0
    fi

    if [ "$SKIP_DOCKER" = false ] && command_exists docker; then
        print_step "尝试启动 MySQL Docker 容器..."

        # 检查容器是否已存在
        if docker ps -a --format 'table {{.Names}}' | grep -q "mysql"; then
            if docker ps --format 'table {{.Names}}' | grep -q "mysql"; then
                print_success "✓ MySQL 容器已在运行"
                return 0
            else
                print_step "启动现有 MySQL 容器..."
                docker start mysql
                print_success "✓ MySQL 容器已启动"
                return 0
            fi
        fi

        # 启动新容器
        docker run -d --name mysql \
            -e MYSQL_ROOT_PASSWORD=yourpassword \
            -p 3306:3306 \
            mysql:8.0

        print_success "✓ MySQL Docker 容器已启动"
        return 0
    else
        print_warning "⚠️  请手动安装 MySQL 或使用 Docker"
        return 1
    fi
}

# 检查端口占用
check_ports() {
    print_step "检查端口占用..."

    local ports=(5000 44300 5432 3306 1433 6379)

    for port in "${ports[@]}"; do
        if lsof -i :"$port" >/dev/null 2>&1; then
            print_warning "⚠️  端口 $port 已被占用"
            lsof -i :"$port"
        else
            print_success "✓ 端口 $port 可用"
        fi
    done
}

# 设置项目
setup_project() {
    print_step "设置项目..."

    # 检查项目路径
    if [ ! -d "$PROJECT_PATH" ]; then
        print_error "✗ 项目路径不存在: $PROJECT_PATH"
        return 1
    fi

    # 进入项目目录
    cd "$PROJECT_PATH"

    # 检查解决方案文件
    local sln_file=$(find . -name "*.sln" | head -n 1)
    if [ -z "$sln_file" ]; then
        print_error "✗ 未找到解决方案文件"
        return 1
    fi

    print_success "✓ 找到解决方案文件: $(basename "$sln_file")"

    # 恢复 NuGet 包
    print_step "恢复 NuGet 包..."
    if dotnet restore; then
        print_success "✓ NuGet 包恢复成功"
    else
        print_error "✗ NuGet 包恢复失败"
        return 1
    fi

    # 编译项目
    print_step "编译项目..."
    if dotnet build --configuration Debug; then
        print_success "✓ 项目编译成功"
    else
        print_error "✗ 项目编译失败"
        return 1
    fi

    return 0
}

# 创建配置文件
create_config_file() {
    print_step "创建配置文件..."

    # 查找 API 项目
    local api_project=$(find . -name "*HttpApi.Host.csproj" | head -n 1)
    if [ -z "$api_project" ]; then
        print_error "✗ 未找到 API 项目"
        return 1
    fi

    local api_project_dir=$(dirname "$api_project")
    local config_path="$api_project_dir/appsettings.Development.json"

    if [ -f "$config_path" ] && [ "$FORCE" != true ]; then
        print_warning "⚠️  配置文件已存在: $config_path"
        print_warning "使用 --force 参数覆盖现有配置"
        return 0
    fi

    # 获取连接字符串
    local connection_string=""
    case "$DATABASE_TYPE" in
        "SqlServer")
            connection_string="Server=localhost;Database=AgentPlatform;User Id=sa;Password=yourStrong(!)Password;TrustServerCertificate=true;"
            ;;
        "PostgreSQL")
            connection_string="Host=localhost;Database=AgentPlatform;Username=postgres;Password=yourpassword;"
            ;;
        "MySQL")
            connection_string="Server=localhost;Database=AgentPlatform;User=root;Password=yourpassword;"
            ;;
        *)
            connection_string="Server=localhost;Database=AgentPlatform;Trusted_Connection=True;TrustServerCertificate=true;"
            ;;
    esac

    # 创建配置文件
    cat > "$config_path" << EOF
{
  "ConnectionStrings": {
    "Default": "$connection_string",
    "Redis": "localhost:6379"
  },
  "App": {
    "ServerRootAddress": "https://localhost:44300/",
    "ClientRootAddress": "http://localhost:4200/",
    "CorsOrigins": "http://localhost:4200,http://localhost:8080,http://localhost:3001"
  },
  "AuthServer": {
    "Authority": "https://localhost:44300/",
    "RequireHttpsMetadata": "false",
    "SwaggerClientId": "AgentPlatform_Swagger",
    "SwaggerClientSecret": "1q2w3e*"
  },
  "AI": {
    "ModelProviders": {
      "OpenAI": {
        "ApiKey": "your-openai-api-key",
        "BaseUrl": "https://api.openai.com/v1/"
      },
      "ZhipuAI": {
        "ApiKey": "your-zhipuai-api-key",
        "BaseUrl": "https://open.bigmodel.cn/api/paas/v4/"
      }
    }
  },
  "EnhancedModelService": {
    "EnableEnhancedFeatures": true,
    "MonitoringConfig": {
      "Enabled": true,
      "EnableDetailedLogging": true
    }
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "CKY.AgentPlatform": "Debug",
      "Microsoft": "Warning",
      "Microsoft.EntityFrameworkCore": "Information"
    }
  }
}
EOF

    print_success "✓ 配置文件已创建: $config_path"
    return 0
}

# 运行数据库迁移
run_database_migration() {
    if [ "$SKIP_DATABASE" = true ]; then
        print_warning "⚠️  跳过数据库迁移"
        return 0
    fi

    print_step "运行数据库迁移..."

    # 查找数据库迁移项目
    local migrator_project=$(find . -name "*DbMigrator.csproj" | head -n 1)
    if [ -z "$migrator_project" ]; then
        print_error "✗ 未找到数据库迁移项目"
        return 1
    fi

    local migrator_project_dir=$(dirname "$migrator_project")
    cd "$migrator_project_dir"

    if dotnet run --environment Development; then
        print_success "✓ 数据库迁移成功"
        return 0
    else
        print_error "✗ 数据库迁移失败"
        return 1
    fi
}

# 显示后续步骤
show_next_steps() {
    echo
    print_info "🎯 设置完成！后续步骤："
    print_warning "1. 编辑配置文件中的 API Key:"
    print_warning "   - 打开 appsettings.Development.json"
    print_warning "   - 替换 'your-openai-api-key' 为真实的 OpenAI API Key"
    print_warning "   - 替换 'your-zhipuai-api-key' 为真实的智谱AI API Key"

    echo
    print_warning "2. 启动应用:"
    print_warning "   - 在 Visual Studio 中打开解决方案"
    print_warning "   - 设置 CKY.AgentPlatform.HttpApi.Host 为启动项目"
    print_warning "   - 按 F5 启动调试"

    echo
    print_warning "3. 验证应用:"
    print_warning "   - 访问 https://localhost:44300/swagger/"
    print_warning "   - 访问 https://localhost:44300/health"

    echo
    print_warning "4. 调试提示:"
    print_warning "   - 使用 F10/F11 进行单步调试"
    print_warning "   - 查看输出窗口中的日志"
    print_warning "   - 检查 Swagger UI 进行 API 测试"
}

# 显示帮助信息
show_help() {
    cat << EOF
AI Agent Platform 开发环境设置脚本

用法: $0 [选项]

选项:
    --database-type TYPE     数据库类型 (SqlServer|PostgreSQL|MySQL) [默认: SqlServer]
    --project-path PATH       项目路径 [默认: 当前目录]
    --skip-database          跳过数据库设置
    --skip-docker           跳过 Docker 检查
    --force                 强制覆盖现有配置文件
    --help                  显示此帮助信息

示例:
    $0                                      # 使用默认设置
    $0 --database-type PostgreSQL           # 使用 PostgreSQL
    $0 --skip-database --skip-docker       # 跳过数据库和 Docker
    $0 --force --project-path /path/to/project  # 强制设置指定项目
EOF
}

# 解析命令行参数
DATABASE_TYPE="SqlServer"
PROJECT_PATH="."
SKIP_DATABASE=false
SKIP_DOCKER=false
FORCE=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --database-type)
            DATABASE_TYPE="$2"
            shift 2
            ;;
        --project-path)
            PROJECT_PATH="$2"
            shift 2
            ;;
        --skip-database)
            SKIP_DATABASE=true
            shift
            ;;
        --skip-docker)
            SKIP_DOCKER=true
            shift
            ;;
        --force)
            FORCE=true
            shift
            ;;
        --help)
            show_help
            exit 0
            ;;
        *)
            print_error "未知选项: $1"
            show_help
            exit 1
            ;;
    esac
done

# 主函数
main() {
    echo -e "\033[35m🚀 AI Agent Platform 开发环境设置脚本\033[0m"
    echo -e "\033[35m=========================================\033[0m"
    echo

    # 显示配置信息
    print_info "配置信息:"
    print_info "  数据库类型: $DATABASE_TYPE"
    print_info "  项目路径: $PROJECT_PATH"
    print_info "  跳过数据库: $SKIP_DATABASE"
    print_info "  跳过 Docker: $SKIP_DOCKER"
    print_info "  强制覆盖: $FORCE"
    echo

    # 检查必要组件
    print_step "检查开发环境..."
    local dotnet_ok=false
    local git_ok=false
    local node_ok=false
    local docker_ok=false

    check_dotnet && dotnet_ok=true
    check_git && git_ok=true
    check_node && node_ok=true
    check_docker && docker_ok=true

    echo
    check_ports

    if [ "$dotnet_ok" = false ] || [ "$git_ok" = false ]; then
        print_error "❌ 必要组件检查失败，请先安装缺失的组件"
        exit 1
    fi

    # 设置数据库
    echo
    local database_ok=false
    setup_database && database_ok=true

    # 设置项目
    echo
    local project_ok=false
    setup_project && project_ok=true

    if [ "$project_ok" = false ]; then
        print_error "❌ 项目设置失败"
        exit 1
    fi

    # 创建配置文件
    echo
    local config_ok=false
    create_config_file && config_ok=true

    # 运行数据库迁移
    if [ "$database_ok" = true ]; then
        echo
        local migration_ok=false
        run_database_migration && migration_ok=true
    else
        print_warning "⚠️  跳过数据库迁移"
        local migration_ok=true
    fi

    # 总结
    echo
    print_step "设置结果："
    print_success "✓ .NET SDK: $([ "$dotnet_ok" = true ] && echo "正常" || echo "异常")"
    print_success "✓ Git: $([ "$git_ok" = true ] && echo "正常" || echo "异常")"
    print_success "✓ Node.js: $([ "$node_ok" = true ] && echo "正常" || echo "异常")"
    print_success "✓ Docker: $([ "$docker_ok" = true ] && echo "正常" || echo "异常")"
    print_success "✓ 数据库: $([ "$database_ok" = true ] && echo "正常" || echo "异常")"
    print_success "✓ 项目: $([ "$project_ok" = true ] && echo "正常" || echo "异常")"
    print_success "✓ 配置文件: $([ "$config_ok" = true ] && echo "正常" || echo "异常")"
    print_success "✓ 数据库迁移: $([ "$migration_ok" = true ] && echo "正常" || echo "异常")"

    if [ "$project_ok" = true ] && [ "$config_ok" = true ]; then
        echo
        print_success "✅ 开发环境设置成功！"
        show_next_steps
    else
        echo
        print_error "❌ 开发环境设置失败，请检查错误信息"
        exit 1
    fi
}

# 执行主函数
main "$@"